package org.jeecg.modules.rental.service.impl;
import java.time.LocalDateTime;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.jeecg.boot.starter.lock.client.RedissonLockClient;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.rental.vo.LoginRentalAccount;
import org.jeecg.modules.iot.cache.EBikeCache;
import org.jeecg.modules.iot.model.power.TaiPower;
import org.jeecg.modules.rental.entity.RentalAccountEBike;
import org.jeecg.modules.rental.entity.RentalEBike;
import org.jeecg.modules.rental.entity.RentalEbikeShare;
import org.jeecg.modules.rental.mapper.RentalAccountEBikeMapper;
import org.jeecg.modules.rental.mapper.RentalEBikeMapper;
import org.jeecg.modules.rental.mapper.RentalEbikeShareMapper;
import org.jeecg.modules.rental.resp.AccountEBikeResp;
import org.jeecg.modules.rental.resp.MyEBikeResp;
import org.jeecg.modules.rental.service.IRentalAccountEBikeService;
import org.jeecg.modules.rental.service.IRentalEbikeShareService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description: 账户车辆
 * @Author: sean
 * @Date:   2024-12-20
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class RentalAccountEBikeServiceImpl extends ServiceImpl<RentalAccountEBikeMapper, RentalAccountEBike> implements IRentalAccountEBikeService {

    private final RentalEBikeMapper rentalEBikeMapper;
    private final RentalEbikeShareMapper rentalEbikeShareMapper;
    private final IRentalEbikeShareService rentalEbikeShareService;
    private final RedissonLockClient redissonLock;
    private final String BIND_EBIKE_LOCK = "rental:bind:ebike:";

    private final EBikeCache eBikeCache;

    @Override
    public List<MyEBikeResp> ebikeList() {
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        List<RentalAccountEBike> existingEBikeList = baseMapper
                .selectList(new QueryWrapper<RentalAccountEBike>()
                        .eq("account_id",  rentalAccount.getId()));
        if(ObjectUtil.isNotEmpty(existingEBikeList)){
            List<Long> ebikeIds = existingEBikeList.stream()
                    .map(RentalAccountEBike::getEbikeId).collect(Collectors.toList());
            List<RentalEBike> eBikeList = rentalEBikeMapper.selectBatchIds(ebikeIds);
            List<MyEBikeResp> eBikeRespList = new ArrayList<>();
            eBikeList.stream().forEach(item->{
                MyEBikeResp myEBikeResp = new MyEBikeResp();
                myEBikeResp.setValue(item.getId().toString());
                myEBikeResp.setName(StrUtil.isNotBlank(item.getCustomCode())?item.getCustomCode():item.getCarCode());
                eBikeRespList.add(myEBikeResp);
            });
            return eBikeRespList;
        }
        return new ArrayList<>();
    }

    @Override
    public Long bindEBike(String equCode) {
        String lockName = BIND_EBIKE_LOCK + equCode;
        boolean lockAcquired = false;
        try {
            lockAcquired = redissonLock.tryLock(lockName, 3);
            if (!lockAcquired) {
                throw new JeecgBootException("common.busy.business");
            }

            //1、查询车辆信息
            RentalEBike rentalCar = rentalEBikeMapper.selectOne(new QueryWrapper<RentalEBike>()
                    .eq("code", equCode).or().eq("car_code", equCode));
            if (ObjectUtil.isEmpty(rentalCar)) {
                throw new JeecgBootException("rentalpayaccount.vehicle.not.exist");
            }

            // 用户当前用户信息
            LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
            //2、校验车辆
            //2.2、当前车辆是否绑定其他账户
            RentalAccountEBike existingEBike = baseMapper
                    .selectOne(new QueryWrapper<RentalAccountEBike>()
                    .eq("ebike_id",  rentalCar.getId()));
            if (ObjectUtil.isNotEmpty(existingEBike)) {
                throw new JeecgBootException("rentalpayaccount.vehicle.bound.someone");
            }
            //3、账户信息添加车辆id
            RentalAccountEBike accountEBike = new RentalAccountEBike();
            accountEBike.setAccountId(rentalAccount.getId());
            accountEBike.setEbikeId(rentalCar.getId());
            baseMapper.insert(accountEBike);

            //取消之前的车辆的控制状态
            List<RentalEbikeShare> ebikeShareList = rentalEbikeShareMapper
                    .selectList(new QueryWrapper<RentalEbikeShare>()
                            .eq("is_ctrl", Boolean.TRUE)
                            .eq("account_id", rentalAccount.getId()));
            if(ObjectUtil.isNotEmpty(ebikeShareList)){
                ebikeShareList.forEach(item->{
                    item.setIsCtrl(Boolean.FALSE);
                });
                rentalEbikeShareService.updateBatchById(ebikeShareList);
            }

            //将自己添加到车辆分享中
            RentalEbikeShare ebikeShare = new RentalEbikeShare();
            ebikeShare.setAccountId(rentalAccount.getId());
            ebikeShare.setEbikeId(rentalCar.getId());
            ebikeShare.setOwnerId(rentalAccount.getId());
            ebikeShare.setIsCtrl(Boolean.TRUE);
            rentalEbikeShareMapper.insert(ebikeShare);
            return rentalCar.getId();
        } catch (Exception e) {
            // 可以在这里处理特定异常，或者简单地重新抛出
            throw e;
        } finally {
            if (lockAcquired) {
                redissonLock.unlock(lockName);
            }
        }
    }

    @Override
    public Boolean unBindEBike(String ids) {
        // 用户当前用户信息
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        List<String> idList = Arrays.asList(ids.split(","));
        List<RentalAccountEBike> accountEBikeList = baseMapper
                .selectList(new QueryWrapper<RentalAccountEBike>().in("ebike_id", idList));
        List<RentalAccountEBike> myEBikeList = accountEBikeList.stream()
                .filter(a-> a.getAccountId().equals(rentalAccount.getId()))
                .collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(myEBikeList)){
            List<Long> accountEBikeIdList = myEBikeList.stream()
                    .map(RentalAccountEBike::getId).collect(Collectors.toList());
            //解散共享群组
            List<RentalEbikeShare> ebikeShareList = rentalEbikeShareMapper
                    .selectList(new QueryWrapper<RentalEbikeShare>()
                            .in("ebike_id", idList));
            if(ObjectUtil.isNotEmpty(ebikeShareList)){
                List<Long> ebikeShareIdList = ebikeShareList.stream()
                        .map(RentalEbikeShare::getId).collect(Collectors.toList());
                rentalEbikeShareMapper.deleteBatchIds(ebikeShareIdList);
            }
            return baseMapper.deleteBatchIds(accountEBikeIdList) > 0;
        }
        return false;
    }

    @Override
    public List<AccountEBikeResp> myEBikeList() {
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        List<RentalAccountEBike> existingEBikeList = baseMapper
                .selectList(new QueryWrapper<RentalAccountEBike>()
                        .eq("account_id",  rentalAccount.getId()));
        if(ObjectUtil.isNotEmpty(existingEBikeList)){
            List<Long> ebikeIds = existingEBikeList.stream()
                    .map(RentalAccountEBike::getEbikeId).collect(Collectors.toList());
            List<RentalEBike> eBikeList = rentalEBikeMapper.selectBatchIds(ebikeIds);
            List<AccountEBikeResp> eBikeRespList = new ArrayList<>();

            existingEBikeList.stream().forEach(item->{
                AccountEBikeResp myEBikeResp = new AccountEBikeResp();
                BeanUtils.copyProperties(item, myEBikeResp);
                Optional<RentalEBike> optional = eBikeList.stream()
                        .filter(a-> a.getId().equals(item.getEbikeId())).findFirst();
                optional.ifPresent(a-> {
                    myEBikeResp.setOnlineStatus(eBikeCache.getVehicleOnlineStatus(a.getCarCode()));
                    TaiPower taiPower = eBikeCache.getVehiclePower(a.getCarCode());
                    if(ObjectUtil.isNotEmpty(taiPower)){
                        myEBikeResp.setSoc(taiPower.getRPowCap());
                    }
                    myEBikeResp.setCode(StrUtil.isNotBlank(a.getCustomCode())?a.getCustomCode():a.getCarCode());
                });
                eBikeRespList.add(myEBikeResp);
            });
            return eBikeRespList;
        }
        return new ArrayList<>();
    }

    @Override
    public Boolean unBindEBike(Long id) {
        // 用户当前用户信息
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        RentalAccountEBike accountEBike = this.getById(id);
        if(ObjectUtil.isNotEmpty(accountEBike) && accountEBike.getAccountId().equals(rentalAccount.getId())){
            //解散共享群组
            List<RentalEbikeShare> ebikeShareList = rentalEbikeShareMapper
                    .selectList(new QueryWrapper<RentalEbikeShare>()
                            .eq("ebike_id", accountEBike.getEbikeId())
                            .eq("owner_id", accountEBike.getAccountId()));
            if(ObjectUtil.isNotEmpty(ebikeShareList)){
                List<Long> ebikeShareIdList = ebikeShareList.stream()
                        .map(RentalEbikeShare::getId).collect(Collectors.toList());
                rentalEbikeShareMapper.deleteBatchIds(ebikeShareIdList);
            }
            return baseMapper.deleteById(id) > 0;
        }
        return false;
    }

}
